﻿#region License and Terms
// MoreLINQ - Extensions to LINQ to Objects
// Copyright (c) 2008 Jonathan Skeet. All rights reserved.
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
//     http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// These methods © 2013 Jon Hanna. Contributed to the above project.
// Licenses under the Apache License, Version 2.0 as per above.
#endregion
namespace MoreLinq
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    public static partial class MoreEnumerable
    {
        private class EmitEnumerator<T> : IEnumerator<T>
        {
            private readonly T _value;
            private bool _moved;
            public EmitEnumerator(T value)
            {
                _value = value;
                _moved = false;
            }
            public T Current
            {
                get { return _value; }
            }
            object IEnumerator.Current
            {
                get { return _value; }
            }
            void IDisposable.Dispose()
            {
            }
            public bool MoveNext()
            {
                if(_moved)
                    return false;
                return _moved = true;;
            }
            public void Reset()
            {
                _moved = false;
            }
        }
        private class EmitEnumerable<T> : IEnumerable<T>
        {
            private readonly T _value;
            public EmitEnumerable(T value)
            {
                _value = value;
            }
            public EmitEnumerator<T> GetEnumerator()
            {
                return new EmitEnumerator<T>(_value);
            }
            IEnumerator<T> IEnumerable<T>.GetEnumerator()
            {
                return GetEnumerator();
            }
            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
        }
        /// <summary>
        /// Creates an <see cref="IEnumerable{T}"/> representing a sequence consiting solely of the value.
        /// </summary>
        /// <param name="value">The value to create a sequence from.</param>
        /// <returns>The single-item sequence.</returns>
        public static IEnumerable<T> Emit<T>(this T value)
        {
            return new EmitEnumerable<T>(value);
        }
        /// <summary>
        /// Creates an <see cref="IEnumerable{T}"/> representing a sequence consiting solely of the value,
        /// unless it is null, in which case an empty sequence is returned.
        /// </summary>
        /// <param name="value">The value to create a sequence from.</param>
        /// <returns>The single-item sequence, or an empty sequence.</returns>
        public static IEnumerable<T> EmitNonNull<T>(this T value)
        {
            return value == null ? (IEnumerable<T>)value.Emit() : Enumerable.Empty<T>();
        }
    }
}